# $Id: networkdb.py ddcad87fab9c 2013/08/17 19:20:30 pgurumur $
# Copyright (c) 2013 Prabhu Gurumurthy <pgurumur@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# File networkdb.py generated on Monday July 01, 2013 @16:14:43 PDT
#
__version__  = "$Revision: ddcad87fab9c $"
__author__   = "$Author: pgurumur $"
__modified__ = "$Date: 2013-08-17 19:20:30Z $"

import time
import datetime
import sys

from sqlalchemy import Column, Integer, String, Numeric, Unicode, Enum
from sqlalchemy import ForeignKey, DateTime, UniqueConstraint
from sqlalchemy.exc import *

from venya.lib import ip
from venya.lib.dbmodel import table, ModelError, tableList
from venya.lib.model import BaseModel, create

def device_types():
   return Enum("router", "switch", "firewall", "loadbalancer")

def record_types():
   return Enum("A", "CNAME", "TXT", "PTR")

def all_tables():
   return tableList.keys()

@table(parent = BaseModel, name = "vendor")
class Vendor(BaseModel):
   name = Column(Unicode(255), nullable = False, unique = True)

   def __str__(self):
      return self.name

@table(parent = BaseModel, name = "service_contract")
class Contract(BaseModel):
   provider = Column(Unicode(100), nullable = False)
   contractid = Column(Unicode(75), nullable = False)
   starttime = Column(DateTime, nullable = True)
   endtime = Column(DateTime, nullable = False)
   __table_args__ = (
         UniqueConstraint('provider', 'contractid', name = 'uc_contract'),
         )

   def __str__(self):
      return self.contractid

@table(parent = BaseModel, name = "device_model")
class DeviceModel(BaseModel):
   vendor = Column(Integer, ForeignKey("vendor.pk"), nullable = False)
   model = Column(Unicode(255), nullable = False)
   devclass = Column(device_types(), nullable = False)
   maxports = Column(Integer, nullable = False)
   contract = Column(Integer, ForeignKey("service_contract.pk"),
         nullable = False)
   __table_args__ = (
         UniqueConstraint('vendor', 'model', name = 'uc_vendor_model'),
         )

   def __str__(self):
      return str(self.model)

@table(parent = BaseModel, name = "site")
class Site(BaseModel):
   name = Column(Unicode(255), nullable = False, unique = True)
   address = Column(Unicode(1000), nullable = True)

   def __str__(self):
      return self.name

@table(parent = BaseModel, name = "vlan")
class Vlan(BaseModel):
   name = Column(Unicode(255), nullable = False)
   number = Column(Integer, nullable = False)
   entity = Column(Integer, ForeignKey("entity.pk"), nullable = False)
   __table_args__ = (
         UniqueConstraint('name', 'entity', name = 'uc_entity_vlan'),
         )

   def save(self, *args, **kwargs):
      if "entity" in kwargs:
         en = Entity(name = kwargs["entity"])
         kwargs["entity"] = en["pk"][0]

      super(Vlan, self).save(*args, **kwargs)

   def __str__(self):
      return self.name

   def __int__(self):
      return self.number

@table(parent = BaseModel, name = "entity")
class Entity(BaseModel):
   name = Column(Unicode(255), nullable = False)
   site = Column(Integer, ForeignKey("site.pk"), nullable = False)
   __table_args__ = (
         UniqueConstraint('name', 'site', name = 'uc_site_entity'),
         )

   def save(self, *args, **kwargs):
      if "site" in kwargs:
         site = Site(name = kwargs["site"])
         kwargs["site"] = site["pk"]

      super(Entity, self).save(*args, **kwargs)

   def __str__(self):
      return self.name

@table(parent = BaseModel, name = "ipblock")
class IPBlock(BaseModel):
   address = Column(Numeric(40, 0), nullable = False)
   prefix = Column(Integer, nullable = False)
   version = Column(Enum("4", "6"), nullable = False)
   gateway = Column(Numeric(40, 0), nullable = False)
   vlan = Column(Integer, ForeignKey("vlan.pk"), nullable = True)
   parent = Column(Integer, ForeignKey("ipblock.pk"), nullable = True)
   dns = Column(Integer, ForeignKey("dns.pk"), nullable = True)

   def save(self):
      print("I am here!")

   def __str__(self):
      return str(self.address)

   def __int__(self):
      return int(self.address)

@table(parent = BaseModel, name = "rack")
class Rack(BaseModel):
   number = Column(Unicode(50), nullable = False)
   site = Column(Integer, ForeignKey("site.pk"), nullable = False)

   __table_args__ = (
         UniqueConstraint('number', 'site', name = 'uc_rack_name'),
         )

   def __str__(self):
      return "%s %s" %(str(self.site), self.number)

@table(parent = BaseModel, name = "dns")
class Dns(BaseModel):
   name = Column(Unicode(50), nullable = False)
   record = Column(record_types(), nullable = False)
   zone = Column(Integer, ForeignKey('zone.pk'), nullable = False)

   __table_args__ = (
         UniqueConstraint('name', 'zone', name = 'uc_name_zone'),
         )

   def __str__(self):
      return self.name

@table(parent = BaseModel, name = "zone")
class Zone(BaseModel):
   name = Column(Unicode(50), nullable = False)
   entity = Column(Integer, ForeignKey('entity.pk'), nullable = False)
   __table_args__ = (
         UniqueConstraint('name', 'entity', name = 'uc_name_entity'),
         )

   def __str__(self):
      return self.name

@table(parent = BaseModel, name = "device")
class Device(BaseModel):
   name = Column(Integer, ForeignKey('dns.pk'), nullable = False)
   entity = Column(Integer, ForeignKey('entity.pk'), nullable = False)
   product = Column(Integer, ForeignKey('device_model.pk'), nullable = False)
   contract = Column(Integer, ForeignKey('service_contract.pk'),
         nullable = False)
   mgmtip = Column(Integer, ForeignKey('ipblock.pk'), nullable = False)
   rack = Column(Integer, ForeignKey('rack.pk'), nullable = False)
   backup = Column(Integer, nullable = True, default = 1)
   monitored = Column(Integer, nullable = True, default = 1)

   def __str__(self):
      return str(self.name)
